package com.beta.resource.controllers;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import java.io.IOException;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.beta.resource.model.UserEnv;
import com.beta.resource.model.UserFile;
import com.beta.resource.services.UserEnvService;
import com.beta.resource.utils.BaseString;
import com.beta.resource.utils.WebSocket;

@Controller
@RequestMapping("/editor")
public class EditorController {
    private static final int INTERNAL_SERVER_ERROR = 500;
    private static final int OK = 200;
    private static final String UPLOAD_SAVE_ERROR_DESC = "An exception occurred while saving the file";
    private static final String OK_DESC = "SUCCESS";

    @Value("${env.mysterious:IamYourFather}")
    private String MYSTERIOUS_INSTRUCTIONS;

    @Resource
    private UserEnvService mUserEnvService;

    @Resource
    private WebSocket mWebSocket;

    @GetMapping(value = { "", "/" })
    public ModelAndView editor(JwtAuthenticationToken token) {
        ModelAndView data = new ModelAndView("editor");
        WebSocket.setEnvService(mUserEnvService);
        UserEnv env = mUserEnvService.getEnv(token);
        data.getModel().put("mecha", env.getInfo().createMechaToken());
        data.getModel().put("uid", env.getInfo().getSuid());
        data.getModel().put("url", WebSocket.LISTENER_URL);
        data.getModel().put("mysterious", BaseString.encodeBase64(MYSTERIOUS_INSTRUCTIONS, null));
        data.getModel().put("title", mUserEnvService.getPageTitle(token));
        data.getModel().put("categories", mUserEnvService.getCategories(token, false));
        data.getModel().put("userfile", mUserEnvService.getDefaultUserFile(token));
        return data;
    }

    @GetMapping("refresh")
    public ModelAndView refresh(JwtAuthenticationToken token,
            @RequestParam(name = "category", required = false, defaultValue = "") String category,
            @RequestParam(name = "index", required = false, defaultValue = "1") int index) {
        ModelAndView data = new ModelAndView("modal::refrescodelist");
        List<UserFile> list = mUserEnvService.getCodeFiles(token, BaseString.decodeBase64(category, UserEnv.CATEGORY_DEFAULT),
                index - 1);
        data.getModel().put("codelist", list);
        if (list == null) {
            data.getModel().put("remaining", 0);
        } else {
            data.getModel().put("remaining", mUserEnvService.getRemainingFiles(token, index));
        }
        return data;
    }

    @GetMapping("pages")
    public ModelAndView getPages(JwtAuthenticationToken token,
            @RequestParam(name = "start", required = true) int start,
            @RequestParam(name = "remaining", required = false, defaultValue = "0") int remaining,
            @RequestParam(name = "index", required = false, defaultValue = "1") int index) {
        ModelAndView data = new ModelAndView("modal::pageindicator");
        data.getModel().put("pagelist", mUserEnvService.calcCurrentPage(token, start, index, remaining));
        return data;
    }

    @PostMapping("/upload")
    @ResponseBody
    public void uploadUserCode(HttpServletResponse response,
            JwtAuthenticationToken token,
            // @ModelAttribute UserFile file) {
            @RequestParam(name = "fid", required = false, defaultValue = "0") int fid,
            @RequestParam(name = "title") String title,
            @RequestParam(name = "category") String category,
            @RequestParam(name = "desc") String desc) {
        UserFile file = new UserFile();
        file.setTitle(title);
        file.setCategory(category);
        file.setDesc(desc);
        file.setId(fid);
        int ret = mUserEnvService.saveFile(token, file);
        response.setStatus(ret > 0 ? OK : INTERNAL_SERVER_ERROR);
        try {
            response.getWriter().append(ret > 0 ? OK_DESC : UPLOAD_SAVE_ERROR_DESC);
            response.getWriter().flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
